package redis.client;

import com.lx.idgenerator.exception.RedisOperationFailException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;

import java.util.Collections;

/**
 * @author lX
 * @version JDK 8
 * @className BackRedisClient (此处以class为例)
 * @date 2024/11/9
 * @description TODO
 */
public class SegmentRedisClient implements RedisClient {
    private final  static Logger logger = LoggerFactory.getLogger(SegmentRedisClient.class);
    
    private RedisTemplate<String,Object> redisTemplate;

    public SegmentRedisClient(RedisTemplate<String,Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    
    @Override
    public Long incr(String key,long step) {
       return redisTemplate.opsForValue().increment(key,step);
    }

    @Override
    public Long get(String key) {
      return   (Long) redisTemplate.opsForValue().get(key);
    }

    @Override
    public void set(String key, long value) {
         redisTemplate.opsForValue().set(key,value);

    }

    @Override
    public Long incrAndGetPrevious(String key,long step) {
        String script = "local key = KEYS[1]\n" +
                "local step = tonumber(ARGV[1])\n" +
                "local currentValue = redis.call('GET', key)\n" +
                "if not currentValue or currentValue == '' then\n" +
                "    currentValue = 0\n" +
                "else\n" +
                "    currentValue = tonumber(currentValue)\n" +
                "end\n" +
                "local oldValue = currentValue\n" +
                "currentValue = currentValue + step\n" +
                "redis.call('SET', key, currentValue)\n" +
                "return oldValue";
        Long result;
        // 执行 Lua 脚本
        try {
             result = (Long) redisTemplate.execute(
                    (RedisCallback<Object>) connection -> {
                        return connection.eval(script.getBytes(), ReturnType.INTEGER, 1, key.getBytes(), String.valueOf(step).getBytes());
                    }
            );

        } catch (Exception e) {
            logger.error("Redis出现异常:{}",e.getStackTrace());
            // 处理异常
            throw new RedisOperationFailException();
        }
  

        return result;  
    }
}
